// ==UserScript== // @name 校友邦实习一键评价 XiaoYouBang Auto Review // @namespace https://github.com/lcandy2/XiaoYouBang-Auto-Review // @version 1.0 // @author lcandy2 // @description 一键评价,自动填写评价内容 // @license MIT // @icon https://www.xybsyw.com/favicon.ico // @match *://www.xybsyw.com/personal/* // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js // @run-at document-start // ==/UserScript== (function ($) { 'use strict'; const config = { autoSubmit: false, // 是否自动提交 day: 1, // 天数类评价 rate: 5, // 评分类评价 1-5 review: "好", // 评价内容 suggestions: "无", // 建议内容 addCourse: "无", // 增加课程 radio: 0, // 单选选择索引,从 0 开始 reviewHref: "myEvaluationDetail" // 评价页面的 href,无特殊情况不需要修改 }; const fillInputs = (inputElement, data) => { new Event("input", { bubbles: true, cancelable: true }); inputElement.focus(); data.split("").forEach((char) => { let keydownEvent = new KeyboardEvent("keydown", { key: char, bubbles: true }); let keyupEvent = new KeyboardEvent("keyup", { key: char, bubbles: true }); let inputEvent = new Event("input", { bubbles: true }); inputElement.dispatchEvent(keydownEvent); inputElement.value += char; inputElement.dispatchEvent(inputEvent); inputElement.dispatchEvent(keyupEvent); }); inputElement.blur(); }; const Review = () => { const $allInput = $("input.el-input__inner"); const $dayInput = $allInput.filter((index, element) => { return $(element).attr("max") !== void 0 && $(element).attr("min") !== void 0; }); const $otherInput = $allInput.not($dayInput); const $courseInput = $otherInput.filter((index, element) => { return $(element).attr("placeholder").includes("课程"); }); const $allRate = $("div.el-rate"); const $allTextarea = $("textarea.el-textarea__inner"); const $suggestTextarea = $allTextarea.filter((index, element) => { return $(element).attr("placeholder").includes("建议"); }); const $otherTextarea = $allTextarea.filter((index, element) => { return !$(element).attr("placeholder").includes("建议"); }); const $allRadio = $("div.radioItem"); $dayInput.each((index, element) => { fillInputs(element, config.day.toString()); }); $courseInput.each((index, element) => { fillInputs(element, config.addCourse); }); $allRate.each((index, element) => { $(element).children().eq(config.rate - 1).trigger("click"); }); $otherTextarea.each((index, element) => { fillInputs(element, config.review); }); $suggestTextarea.each((index, element) => { fillInputs(element, config.suggestions); }); $allRadio.each((index, element) => { $(element).children().eq(config.radio).trigger("click"); }); console.log("Review success!"); }; const addReviewButton = (listener) => { if ($("button.--lcandy2-xyb-auto-review").length) return; const $topContent = $("div.contentItem div.topContent"); const $topContent_item = $topContent.children().eq(1); const $reviewButton = $(``); $reviewButton.on("click", () => { config.autoSubmit = false; listener(); }); const $reviewAndSubmitButton = $(``); $reviewAndSubmitButton.on("click", () => { config.autoSubmit = true; listener(); }); $topContent_item.append($reviewButton); $topContent_item.append($reviewAndSubmitButton); console.log("Add Review Button", $reviewButton); }; const watchUrlChange = (onChange) => { const originalPushState = history.pushState; history.pushState = function(state, title, url) { originalPushState.apply(this, arguments); onChange(url); }; const originalReplaceState = history.replaceState; history.replaceState = function(state, title, url) { originalReplaceState.apply(this, arguments); onChange(url); }; window.addEventListener("popstate", () => { onChange(document.location.href); }); }; const executeReview = async () => { Review(); const $submitButton = $("div.bottomDiv button.submitBtn"); $submitButton.val("评价完成,点击提交评价"); if (config.autoSubmit) { $submitButton.trigger("click"); alert("评价完成,已自动提交。"); } }; const main = () => { const href = window.location.href; if (!href.includes(config.reviewHref)) return; addReviewButton(executeReview); }; $(async () => { main(); watchUrlChange((newUrl) => { console.log("URL 变化了:", newUrl); const observer = new MutationObserver((mutations) => { for (let mutation of mutations) { if (mutation.addedNodes.length) { const $topContent = $("div.contentItem div.topContent"); if ($topContent.length) { observer.disconnect(); main(); break; } } } }); observer.observe(document.body, { childList: true, subtree: true }); }); }); })(jQuery);